package com.sye.threadmodule.thread;

import org.junit.Test;

import java.util.concurrent.*;

public class UseQueue {

    /**
     * 高性能无阻塞,适合高并发场景的队列,通过无锁的方式,实现了高并发下的高性能,通常性能好于BlockingQueue。元素先进先出。
     */
    @Test
    public void useConcurrentLinkedQueue(){
        ConcurrentLinkedQueue<String> q = new ConcurrentLinkedQueue<String>();
        q.offer("a");
        q.offer("b");
        q.offer("c");
        q.offer("d");
        q.add("e");
        System.out.println(q.poll());	//a 从头部取出元素，并从队列里删除
        System.out.println(q.size());	//4 取出元素后不会从队列里面删除
        System.out.println(q.peek());	//b
        System.out.println(q.size());	//4
    }
    /**
     * 基于数组的阻塞队列实现，在其内部维护了一个定长数组，以便于缓存队列中的数据对象，其内部没有读写分离，
     * 也就意味着生产和消费不能完全并行，长度是需要定义的。可以指定先进先出或先进后出，也叫有界队列。
     */
    @Test
    public void useArrayBlockingQueue() throws InterruptedException {
        ArrayBlockingQueue<String> array = new ArrayBlockingQueue<String>(5);
        array.put("a");
        array.put("b");
        array.add("c");
        array.add("d");
        array.add("e");
//        array.add("f");
        System.out.println(array.offer("a", 3, TimeUnit.SECONDS));
    }
    /**
     * 基于链表的阻塞队列，同ArrayBlockingQueue类似，其内部也维护着一个缓冲队列，
     *  (该队列由一个链表构成)，其内部实现读写分离锁，可以实现生产者消费者完全并发运行是一个无界的队列。
     */
    @Test
    public void useLinkedBlockingQueue(){
        LinkedBlockingQueue<String> q = new LinkedBlockingQueue<String>();
        q.offer("a");
        q.offer("b");
        q.offer("c");
        q.offer("d");
        q.offer("e");
        q.add("f");
        System.out.println(q.size());
    }

    /**
     * 一种没有缓冲的队列，生产者产生的数据会被消费者直接获取并消费。
     */
    @Test
    public void uesSynchronousQueue(){
        final SynchronousQueue<String> q = new SynchronousQueue<String>();
//		q.add("PPP"); //这种队列不能直接添加元素,添加元素会报错
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(q.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                q.add("asdasd");
            }
        });
        t2.start();
    }

    /**
     * 基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来)决定，也就是说传入的对象必须实现Comparable接口),
     * 内部实现采用公平锁，是无界队列。**排序是在拿元素的时候才进行排序，添加元素的时候是不排序的
     */
    @Test
    public void usePriorityBlockingQueue() throws InterruptedException {
        PriorityBlockingQueue<Task> q = new PriorityBlockingQueue<Task>();

        Task t0 = new Task();
        t0.setId(5);
        t0.setName("id为5");
        Task t1 = new Task();
        t1.setId(3);
        t1.setName("id为3");
        Task t2 = new Task();
        t2.setId(4);
        t2.setName("id为4");
        Task t3 = new Task();
        t3.setId(1);
        t3.setName("id为1");

        //return this.id > task.id ? 1 : 0;
        q.add(t0);
        q.add(t1);	//3
        q.add(t2);	//4
        q.add(t3);  //1

        // 1 3 4
        System.out.println("容器：" + q);
        System.out.println(q.take().getId());
        System.out.println("容器：" + q);
        System.out.println(q.take().getId());
        System.out.println(q.take().getId());
    }


}
class Task implements Comparable<Task>{

    private int id ;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(Task task) {
        return this.id > task.id ? 1 : (this.id < task.id ? -1 : 0);
    }

    public String toString(){
        return this.id + "," + this.name;
    }

}